package main

import (
	"gitee.com/wx-rdc/secloud-sdk-go/secloud"
	"github.com/antihax/optional"
	"log"
	"strconv"
)

func main() {
	log.Println("============================= Test Begin =============================")
	c := secloud.NewAPIClient(secloud.NewConfiguration("http://kun-gateway:8080"))
	ac, err := c.AuthEntrance.Token(&secloud.AuthOpts{
		ClientId:     optional.NewString("jnS2JqPlNvXejehIhf"),
		ClientSecret: optional.NewString("IflxU3uGCsLaXVpk"),
	})
	if err != nil {
		log.Fatalf("Get AuthClient Fail: %s", err)
	}
	log.Printf("Get AuthClient Successfully!")

	bgTaskId, err := ac.KmsClient.GenerateKey(&secloud.GenerateKeyOpts{
		WorkMode:  optional.NewString("KEK"),
		Algorithm: optional.NewString("SM4"),
		Count:     optional.NewInt(1),
	})
	if err != nil {
		log.Fatalf("Generate Working Key Fail: %s", err)
	}
	log.Printf("Generate Key Successfully! BgTask ID is: %d", bgTaskId.BgTaskId)

	ret, err := ac.KmsClient.QueryBgTask(&secloud.QueryBgTaskOpts{
		BgTaskId: optional.NewString(strconv.FormatInt(bgTaskId.BgTaskId, 10)),
	})
	if err != nil {
		log.Fatalf("Query BgTask Fail: %s", err)
	}
	log.Printf("Query BgTask Sucessfully!")
	log.Println(*ret)

	dks, err := ac.KmsClient.InvokeKey(&secloud.InvokeKeyOpts{
		WorkMode: optional.NewString("KEK"),
		Count:    optional.NewInt(1),
	})
	if err != nil {
		log.Fatalf("Distribute Keys Fail: %s", err)
	}
	log.Printf("Invoke Keys Successfully! KeyID is: %s", dks[0].KeyId)

	ik, err := ac.KmsClient.OpenKeySession(&secloud.OpenKeySessionOpts{
		WorkMode: optional.NewString("KEK"),
		KeyId:    optional.NewString(dks[0].KeyId),
	})
	if err != nil {
		log.Fatalf("Import Key Fail: %s", err)
	}
	log.Printf("Open Key Session Successfully! SessionId is: %s", ik.SessionId)

	enc, err := ac.CipherClient.Encrypt(&secloud.EncryptOpts{
		SessionId: optional.NewString(ik.SessionId),
		PlainText: optional.NewString("123"),
		Algorithm: optional.NewString("Sm4Cbc"),
	})
	if err != nil {
		log.Fatalf("Encrypt Data Fail")
	}
	log.Printf("Encrypt Data Successfully! EncData is: %s", enc.CipherText)

	raw, err := ac.CipherClient.Decrypt(&secloud.DecryptOpts{
		SessionId:  optional.NewString(ik.SessionId),
		CipherText: optional.NewString(enc.CipherText),
		Algorithm:  optional.NewString("Sm4Cbc"),
	})
	if err != nil {
		log.Fatalf("Decrypt Data Fail: %s", err)
	}
	log.Printf("Decrypt Successfully! Raw Data is: %s\n", raw.PlainText)

	_, err = ac.KmsClient.CloseKeySession(&secloud.CloseKeySessionOpts{
		SessionId: optional.NewString(ik.SessionId),
	})
	if err != nil {
		log.Fatalf("Destroy Handle Fail: %s", err)
	}
	log.Printf("Close Key Session Successfully!")

	vd, err := ac.CipherClient.Sign(&secloud.SignOpts{
		PlainText: optional.NewString("1234"),
		Algorithm: optional.NewString("SM2"),
	})
	if err != nil {
		log.Fatalf("Sign Fail: %s", err)
	}
	log.Printf("Sign Successfully! Signature is %s", vd.Signature)

	verify, err := ac.CipherClient.Verify(&secloud.VerifyOpts{
		WorkMode:  optional.NewString("IPK"),
		Algorithm: optional.NewString("SM2"),
		PlainText: optional.NewString("1234"),
		Signature: optional.NewString(vd.Signature),
	})
	if err != nil {
		log.Fatalf("Verify Fail: %s", err)
	}
	log.Printf("Verify Successfully! result is %t", verify.OK)

	_, err = ac.KmsClient.DestroyKey(&secloud.DestroyKeyOpts{
		KeyId: optional.NewString(dks[0].KeyId),
	})
	if err != nil {
		log.Fatalf("Destroy Key Fail: %s", err)
	}
	log.Printf("Destroy Key Successfully!")
}
